A networked computing system, as illustrated in FIG. 1, comprises a server computer 100, having access to database 110 and associated with multiple client computers 150, each having at least one local storage location and a local file system 130 and each adapted to communicate with the server over communication channel 140. The server computer may be a general purpose computer, such as an IBM* RISC System 6000*; the database, a relational database such as DB2*; and, the client computers, notebook computers such as the IBM Thinkpad*, or similar computing devices which communicate with the server by modem. (*Trademarks of International Business Machines Corporation).
Applications running on the illustrated mobile system are implemented using an object-oriented programming language, such as JAVA** (**Trademark of SunMicrosystems, Inc.). The instances of JAVA objects used in the applications are stored in the relational database 110 of the server as tuples, with each object stored in one tuple 210, as shown in FIG. 2a. The transformation from relational tuple to JAVA object occurs in the server. JAVA object serialization is used to stream the data in a JAVA object to an array of bytes, which is then stored as the Object Data 213 of the relational tuple. The object data can be stored in a number of alternative ways, for example, in a large binary field, or with attributes of object mapped to a field in a relational tuple, or such other means as are detailed in an article entitled "Using the Co-existence Approach to Achieve Combined Functionality of Object Oriented and Relational Systems," by R. Ananthanarayanan, et al, ACM-SIGMOD Proceedings (May 1993), pp 108-118. The tuple for an object in the database also contains an object ID, OID 212, which uniquely identifies the object, along with a version number, Vdb 211, which is used for detecting conflicting updates.
The applications running on a mobile system of the type illustrated are transaction-based applications, which use optimistic concurrency control. Optimistic concurrency control is well-known in the art, as detailed in Distributed Systems: Concepts and Design, by Coulouris and Dollimore, (Adison Wesley, 1988), page 181 et seq. Under an optimistic concurrency approach, all transaction updates are automatically allowed, without requiring locks to be acquired. When a transaction attempts to commit, version numbers are checked to determine if any of the objects used in the transaction were modified while the transaction was running. If not, the commit succeeds and the modified objects are written to the database with new version numbers. If any version numbers differ, then the commit fails and the transaction is aborted.
Due to the fact that the bandwidth of the communication channel 140 between the client and the server is limited and can be somewhat unreliable, a disconnected style of operation is used for running applications at the client. Under disconnected system operation, a client wishing to run an application first requests objects from the server, downloads those objects needed by the application, and stores the downloaded objects in a storage location associated with the local file system 130. The client then disconnects from the server, and proceeds to execute one or more transactions locally. When an application commits a local transaction, the transaction is recorded by the client's local file system which dynamically creates a record of the transaction and of the modified object(s). When the client subsequently reconnects with the server, the logged transactions are read from the client's local file system, sent to the server, and replayed on the server, with the modified objects being written back to the server's database 110.
FIG. 3 depicts the logical entities involved when an application is executing on a client while the client is disconnected from the server. Thus far the data items have been referred to as "objects," which would be the data items operated on in an object-oriented programming environment. The term "objects" will be used throughout to refer to data items of any format. A transaction object, as illustrated at 250 of FIG. 3 is created when the application program 260 starts the transaction. The transaction object records the objects 270, shown as OBJECT1 (a READ-ONLY object, as indicated by the unidirectional communication lines), OBJECT2 . . . OBJECTn, being used by the transaction. These objects reside in volatile memory, having been retrieved from the client's Local Object Store 400 where the objects had been stored after downloading from the server. While transactions are running, the fact of modification is being recorded in the lock mode field 217 of the object shown at 2b. When the application commits the transaction, modified objects are written to the Local Object Store 400 and the transaction is logged, along with, representatively, lock mode and location information, in the client's Transaction Log 500.
The client's Local Object Store is responsible for storing objects resident on the client, and is implemented using the client local file system. FIG. 4 shows details for an implementation of a Local Object Store 400 at a client computer. The Local Object Store contains multiple ClassStores 420, one for each object class that has instances stored on the client. The ClassStores are identified by the name of each class and the Local Object Store additionally builds and maintains a ClassStore index 401 which maps the name of a class to the ClassStore object for that class.
Each ClassStore has an Object Data file 422 which stores instances of objects 220, and an object Index 421 which is used to locate objects in the Object Data File. When objects are resident on the client, the object, 220 as shown in FIG. 2b, contain additional control fields. Beyond the object ID 212 and the object data 213, the object additionally includes the transaction ID, 214, of the client transaction which created that version of the object; the version number of the object, Vc, at 215, set at the time the creating transaction committed; Vi, 216, which is the version number of the initial version of the object that was read by the transaction identified by the TID; and Lock Mode, 217, which indicates whether an object has been modified or has only been read by the running transaction, 250.
The Object Index is indexed by Object ID, OID 212. The index entries are Object References (hereinafter referred to as "Object Refs") 230, 230', and 230", which are detailed in FIG. 2c. The offset 219 and length 221 fields of the index Object Refs are used to specify where to find the corresponding object instance in the Object Data file 422.
A ClassStore contains the initial server version of each object which was downloaded from the server before the client disconnected. It also contains each of the modified versions of objects, created by transactions which run on the client while disconnected. Thus, a ClassStore is capable of storing multiple versions of the same object, (i.e., having the same OID). The different versions of an object are identified, and differentiated, by the Transaction Identifier (hereinafter, "TID") of the client transaction which made the modifications to the object. In the Object Index, Object Refs for the different versions of an object, having the same OID and different TIDs, are linked together by the "next" field 222 in the Object Refs.
When a new or modified object is stored in the ClassStore for the object's class, the object is serialized to a byte array, using JAVA** object serialization; the byte array is written to the Object Data File 422,; and, an Object Ref 230 if created. In addition, the Object Ref ClassName 218 is set to the name of the class of the object; the offset field 219 is set to the location of the object byte array in the file; and, the length field is set to the size of the object byte array. The OID in the new Ref is set to the object's OID, and the TID in the Ref is set to the transaction which created or modified the object being written. The version numbers, V.sub.i for the initial version and V.sub.c for the version at commit, are copied from the object and the new object Ref is added to the linked list of Object Refs for objects having the same OID. The version "number" need not necessarily be a sequential numerical value, provided that it is a globally unique characteristic which identifies the object version. For one implementation of the present invention, the version "number" comprises a combination of a time stamp, a one-up number, and the CPU number. The new Object Ref is added to the top of the list and the index entry for that OID is changed to point to the new Object Ref, so that the list of Object Refs is ordered by time of insertion, with the most recent version being first on the list.
FIG. 4 shows Object Refs 230, 230' and 230" including the index structure for versions of a single object having OID=11. Three versions of the object are stored in the ClassStore including the initial download version, having TID=0, and the versions created by client transactions 4 and 8. A TID value of 0 is used for initial versions of objects downloaded from the server.
The client Local Object Store and its ClassStores support two basic retrieval operations. One operation is retrieval of the most recent version of an object, given its ClassName and OID, which is used by running transactions for retrieving an object from the Local Object Store. The second operation is retrieval of a specific version of an object, given its ClassName, OID, and TID. The latter retrieval operation is required for replaying of logged actions on the server when a client reconnects, which operation is the subject of the present invention.
The client Transaction Log, shown at 500, is responsible for logging transactions executed on the client while it is disconnected from the server, and also uses the client local file system. When an application running on a disconnected client commits its current transaction, it causes a "Local Commit" which logs the transaction in the client's Transaction Log 500 for subsequent replay on the server. FIG. 7 details the processing for a local commit operation on the client computer, as detailed below.
FIG. 5 depicts the client Transaction Log 500 comprising a Transaction Log File 510 and a Transaction File 520 for each locally committed transaction, which contains the TID of the transaction. The Transaction File contains Object Refs 239 for objects in the transaction's Read Set and Write Set. Refs for objects in the Write Set will all have a TID field whose value is the TID of the committed transaction, since the transaction created those versions of the objects. Refs for objects in the Read Set will all have a TID field which differs from that of the committed transaction, since a previous transaction created that version of the object which is simply being read by the current transaction.
The Transaction File does not store the actual contents of the objects which have been modified by the transaction. Rather, the modified objects are written to the Local Object Store during processing of the local commit. When a transaction is replayed, the objects modified by the transaction are retrieved from the Local Object Store, using the ClassName, OID, and TID values in the Object Refs from the transaction's Write Set (wherein the TID will match that of the transaction being replayed).
When processing a local commit operation, as shown in FIG. 7, the client computer computes the time for the commit, T.sub.c, at 71, and obtains the Read Set of objects which were only read during the transaction, at 72. Next, at 73, the client obtains the Write Set containing those objects which had been modified during the transaction; and at 74, for each object in the Write Set, the client sets the TID for the transaction, sets the version number, V.sub.c, in the object to T.sub.c, and writes the modified object to the Local Object Store. Next, at 75, the client creates a Transaction File for the committing transaction and writes the Object Refs for each object in the Read Set and Write Set to the Transaction File at 76. Finally, at 77, the client writes a log record for the transaction to the Transaction Log File.
When a client reconnects with the server, it is necessary to replay on the server all of the transactions which executed, were locally committed, and were logged at the client while it was disconnected. The simplest strategy for replaying transactions is to replay the transactions one by one in the order in which they executed on the client. For each logged transaction, the system reconstructs the final state of the transaction Read Set and Write Set at the time that the transaction was committed. The Read Set 521, consisting of Object Refs 230, but not the actual objects, for objects read by the transaction, is found in the Transaction File 520 of the client's Transaction Log. The Write Set, consisting of new objects and objects modified by the transaction, is accessed by using the Object Refs in the Transaction File Write Set 522, including the ClassName, OID, and TID, to retrieve the created and modified versions of the objects from the Local Object Store.
The Read Set of Object Refs and Write Set of objects are sent to the server to be replayed. "Replay" in this context does not mean re-executing the logic of the application. Rather, it means attempting to commit the final state of the client transaction against the server's database, as if the transaction had just executed at the server. The procedure for committing a client transaction during replay employs standard "optimistic concurrency control" techniques. The server begins a database transaction and compares the initial version numbers of all objects in the Read Set and Write Set to the version numbers of the same objects in the server database. If the initial version numbers differ for any object (indicative of the fact that the version has been modified at the server), the server rejects the transaction. The rejected transactions are typically logged on the server for subsequent conflict resolution, the details of which are not the subject of the present invention. If, however, all initial version numbers match, then the objects in the Write Set are written to the database with new version numbers; the server transaction is committed, and the replay succeeds. When using this basic replay strategy, the logged client transactions are replayed one by one in sequence, independent of whether or not any of the preceding transactions failed during replay at the server. A disadvantage of such sequential replay is that the intermediate versions of objects that have been modified several times must each be replayed, only to be replaced in short order. The unnecessary replay iterations consume bandwidth on the communications links and usurp valuable server time and resources.
It is therefore an objective of the present invention to provide a method for computing a combined transaction at the client from a set of logged client transactions which are waiting to be replayed.
It is another objective of the invention to provide a combined transaction to the server for replay whereby bandwidth and server CPU time are utilized most efficiently.